/*
 * SerialHelper.cpp
 *
 *  Created on: Jul 1, 2011
 *      Author: jrodrig9
 */
 
/////////////////////////////////////////////////
// Serial port interface program               //
/////////////////////////////////////////////////
 
#include <stdio.h> // standard input / output functions
#include <string.h> // string function definitions
#include <unistd.h> // UNIX standard function definitions
#include <fcntl.h> // File control definitions
#include <errno.h> // Error number definitions
#include <termios.h> // POSIX terminal control definitions
#include <time.h>   // time calls
 
#include "SerialHelper.h"
 
SerialHelper::SerialHelper(int a) {
 
    serial_port_number = a;
    file_pointer = open_port(serial_port_number);
    configure_port(fd);
    query_modem(fd);
}
 
SerialHelper::SerialHelper() {
 
    a = 2;
    serial_port_number = a;
    file_pointer = open_port(serial_port_number);
    configure_port(fd);
    query_modem(fd);
}
 
int SerialHelper::open_port(int a)
{
    int fd; // file description for the serial port
 
    switch(a){
    case 0:
        fd = open("/dev/ttySAC0", O_RDWR | O_NOCTTY | O_NDELAY);
        break;
    case 1:
        fd = open("/dev/ttySAC1", O_RDWR | O_NOCTTY | O_NDELAY);
        break;
    case 2:
        fd = open("/dev/ttySAC2", O_RDWR | O_NOCTTY | O_NDELAY);
        break;
    case 3:
        fd = open("/dev/ttySAC3", O_RDWR | O_NOCTTY | O_NDELAY);
        break;
    default:
        fd = open("/dev/ttySAC0", O_RDWR | O_NOCTTY | O_NDELAY);
        break;
    }
 
 
    if(fd == -1) // if open is unsucessful
    {
        //perror("open_port: Unable to open /dev/ttyS0 - ");
        printf("open_port: Unable to open /dev/ttySACX. \n");
    }
    else
    {
        fcntl(fd, F_SETFL, 0);
        printf("port is open.\n");
    }
 
    return(fd);
} //open_port
 
int SerialHelper::configure_baud_rate(int set_speed)      // configure the baud rate
{
    struct termios port_settings;      // structure to store the port settings in

    //This is an extremely crappy way of doing this, but I have to do
    //what I know will work w/o a board
    // 8=1800 bps, 7=2400 bps, 6=4800 bps
    // 5=9600 bps, 4=19200 bps, 3=38400 bps
    // 2=57600 bps, 1=115200 bps

    switch(set_speed){ // set baud rates
    case 1:
		cfsetispeed(&port_settings, B115200);
		cfsetospeed(&port_settings, B115200);
		break;
    case 2:
		cfsetispeed(&port_settings, B57600);
		cfsetospeed(&port_settings, B57600);
		break;
    case 3:
		cfsetispeed(&port_settings, B38400);
		cfsetospeed(&port_settings, B38400);
		break;
    case 4:
		cfsetispeed(&port_settings, B19200);
		cfsetospeed(&port_settings, B19200);
		break;
    case 5:
		cfsetispeed(&port_settings, B9600);
		cfsetospeed(&port_settings, B9600);
		break;
    case 6:
		cfsetispeed(&port_settings, B4800);
		cfsetospeed(&port_settings, B4800);
		break;
    case 7:
		cfsetispeed(&port_settings, B2400);
		cfsetospeed(&port_settings, B2400);
		break;
    case 8:
		cfsetispeed(&port_settings, B1800);
		cfsetospeed(&port_settings, B1800);
		break;
    }


    port_settings.c_cflag &= ~PARENB;    // set no parity, stop bits, data bits
    port_settings.c_cflag &= ~CSTOPB;
    port_settings.c_cflag &= ~CSIZE;
    port_settings.c_cflag |= CS8;

    tcsetattr(fd, TCSANOW, &port_settings);    // apply the settings to the port
    return(fd);

} //configure_port

int SerialHelper::configure_port(int fd)      // configure the port
{
    struct termios port_settings;      // structure to store the port settings in
 
    cfsetispeed(&port_settings, B115200);    // set baud rates
    cfsetospeed(&port_settings, B115200);
 
    port_settings.c_cflag &= ~PARENB;    // set no parity, stop bits, data bits
    port_settings.c_cflag &= ~CSTOPB;
    port_settings.c_cflag &= ~CSIZE;
    port_settings.c_cflag |= CS8;
 
    tcsetattr(fd, TCSANOW, &port_settings);    // apply the settings to the port
    return(fd);
 
} //configure_port
 
void SerialHelper::write_to_port_Bytes(unsigned char bytes_in[], int message_size){
 
    unsigned char bytes_to_send[] = bytes_in;
    write(file_pointer, bytes_to_send, message_size);
    //printf("Wrote the bytes. \n");
}

void SerialHelper::write_to_port_Byte(unsigned char byte_in){
	write(file_pointer,byte_in,1);
}
 
int SerialHelper::getfile_pointer(){
    return file_pointer;
}
 
int SerialHelper::query_modem(int fd)   // query modem with an AT command
{
    char n;
    fd_set rdfs;
    struct timeval timeout;
 
    // initialise the timeout structure
    timeout.tv_sec = 10; // ten second timeout
    timeout.tv_usec = 0;
 
    //Create byte array
    unsigned char send_bytes[] = { 0x02, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x23, 0x01, 0x21, 0x03};
 
 
    write(fd, send_bytes, 13);  //Send data
    printf("Wrote the bytes. \n");
 
    // do the select
    n = select(fd + 1, &rdfs, NULL, NULL, &timeout);
 
    // check if an error has occured
    if(n < 0)
    {
     perror("select failed\n");
    }
    else if (n == 0)
    {
     puts("Timeout!");
    }
    else
    {
     printf("\nBytes detected on the port!\n");
    }
 
    return 0;
 
} //query_modem
